iT邦幫忙

0

Flutter Bloc Counter 練習

  • 分享至 

  • xImage
  •  

我們用簡單的計數器,學習怎麼使用Cubit來存取狀態。

Dependency

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter

  bloc: ^8.1.0
  flutter_bloc: ^8.1.1

Counter Cubit

CounterCubit 用來儲存 int 狀態,所以繼承於 Cubit<int>,emit 是用來更改現在有狀態。

  • increment:將狀態加 1
  • decrement:將狀態減 1

lib/counter/cubit/counter_cubit.dart:

class CounterCubit extends Cubit<int> {
	CounterCubit(): super(0);
	
	void increment() => emit(state + 1);
	
	void decrement() => emit(state -1);
}

Counter View

CounterView 用來呈現計數器的畫面,用 BlocBuilder 來呼叫 CounterCubit 的方法與存取它的狀態值。當 state 有變化的時候,BlocBuilder 就會幫我們重繪畫面,不用再需要setState() 來重繪。
context.read() 可以用來呼叫 CounterCubit 的方法。

lib/counter/view/counter_view.dart:


class CounterView extends StatelessWidget {
  const CounterView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;
    return Scaffold(
      appBar: AppBar(
        title: const Text('Counter'),
        centerTitle: true,
      ),
      body: Center(
        child: BlocBuilder<CounterCubit, int>(builder: (context, state) {
          return Text('\$state', style: textTheme.headline2);
        }),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          FloatingActionButton(
            key: const Key("counterView_increment_floatingActionButton"),
            child: const Icon(Icons.add),
            onPressed: () => context.read<CounterCubit>().increment(),
          ),
          const SizedBox(
            height: 8,
          ),
          FloatingActionButton(
            key: const Key("counterView_decrement_floatingActionButton"),
            child: const Icon(Icons.remove),
            onPressed: () => context.read<CounterCubit>().decrement(),
          )
        ],
      ),
    );
  }
}

輸入 stl+enter,可以快速產生一個繼承於 StatelessWidget 的類別。

Export

可以用一個同名的目錄檔案,可以用來整理 import library,讓程式上面的 import 檔案能夠統一管理。

lib/counter/counter.dart:

export 'cubit/counter_cubit.dart';

Counter Page

CounterPage 是將 CounterCubit 實體化,然後提供給 CounterView。

lib/counter/view/counter_page.dart:

class CounterPage extends StatelessWidget {
  const CounterPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
        create: (_) => CounterCubit(), child: const CounterView());
  }
}

App

lib/app.dart

class CounterApp extends MaterialApp {
  const CounterApp({super.key}) : super(home: const CounterPage());
}

BlocObserver

可以用 CounterObserver 繼承 BlocObserver 來監控應用程式裡,所有的狀態。

lib/counter_observer

class CounterObserver extends BlocObserver {
  @override
  void onChange(BlocBase bloc, Change change) {
    super.onChange(bloc, change);
    print('${bloc.runtimeType} $change');
  }
}

lib/main.dart

void main() {
	Bloc.observer = CounterObserver();
 	runApp(const CounterApp());
}

Summary

計數器的程式架構將實作層從業務邏輯層分開來,把業務邏輯寫在 CounterCubit 裏面,CounterView 只要負責通知 CounterCubit。CounterCubit 也只要負責將新狀態回傳。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言